package com.maomao.config;

import com.alibaba.csp.sentinel.util.StringUtil;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;

import java.util.List;

/**
 * 多租户处理器实现类
 */
public class MultiTenantHandler implements TenantLineHandler {

    private final TenantProperties properties;

    public MultiTenantHandler(TenantProperties properties) {
        this.properties = properties;
    }

    /**
     * 获取租户ID值表达式，只支持单个ID值 (实际应该从用户信息中获取)
     *
     * @return 租户ID值表达式
     */
    @Override
    public Expression getTenantId() {
        // 实际应该从用户信息中获取，框架一般都有获取用户信息的接口
        String tenant_id = "";
        // 判空校验
        if (StringUtil.isNotEmpty(tenant_id)) {
            return new StringValue(tenant_id);
        }
        return new StringValue("");
    }

    /**
     * 获取租户字段名,默认字段名叫: tenant_id
     *
     * @return 租户字段名
     */
    @Override
    public String getTenantIdColumn() {
        return properties.getColumn();
    }

    /**
     * 根据表名判断是否忽略拼接多租户条件
     * <p>
     * 默认都要进行解析并拼接多租户条件
     *
     * @param tableName 表名
     * @return 是否忽略, true:表示忽略，false:需要解析并拼接多租户条件
     */
    @Override
    public boolean ignoreTable(String tableName) {
        // 自定义注解忽略拦截（可选，有的场景是获取不到登录用户信息的，比如系统内部调用接口，所以用一个内存变量来存储是否忽略校验）

        if (null != TenantContext.getCurrentTenant()) {
            return true;
        }

        // 可以自行增加一些校验比如获取不到用户就直接 return false 之类的。

        // 忽略指定用户对租户的数据过滤
        String username = "";
        if (null != properties.getIgnoreLoginNames() && properties.getIgnoreLoginNames().contains(username)) {
            return true;
        }

        // 忽略指定表对租户数据的过滤
        List<String> ignoreTables = properties.getIgnoreTables();
        if (null != ignoreTables && ignoreTables.contains(tableName)) {
            return true;
        }
        return false;
    }
}
